home *** CD-ROM | disk | FTP | other *** search
- /* -*- C -*-
- ** Astrolog (Version 4.40) File: xscreen.c
- **
- ** IMPORTANT NOTICE: The graphics database and chart display routines
- ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
- ** (astara@u.washington.edu). Permission is granted to freely use and
- ** distribute these routines provided one doesn't sell, restrict, or
- ** profit from them in any way. Modification is allowed provided these
- ** notices remain with any altered or edited versions of the program.
- **
- ** The main planetary calculation routines used in this program have
- ** been Copyrighted and the core of this program is basically a
- ** conversion to C of the routines created by James Neely as listed in
- ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
- ** available from Matrix Software. The copyright gives us permission to
- ** use the routines for personal use but not to sell them or profit from
- ** them in any way.
- **
- ** The PostScript code within the core graphics routines are programmed
- ** and Copyright (C) 1992-1993 by Brian D. Willoughby
- ** (brianw@sounds.wa.com). Conditions are identical to those above.
- **
- ** The extended accurate ephemeris databases and formulas are from the
- ** calculation routines in the program "Placalc" and are programmed and
- ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
- ** (alois@azur.ch). The use of that source code is subject to
- ** regulations made by Astrodienst Zurich, and the code is not in the
- ** public domain. This copyright notice must not be changed or removed
- ** by any user of this program.
- **
- ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
- ** X Window graphics initially programmed 10/23-29/1991.
- ** PostScript graphics initially programmed 11/29-30/1992.
- ** Last code change made 1/29/1995.
- */
-
- /* $VER: $Id: xscreen.c,v 1.4 1995/07/02 22:23:01 tf Exp $ */
-
- #include "astrolog.h"
-
-
- #ifdef GRAPH
- /*
- ******************************************************************************
- ** Astrolog Icon.
- ******************************************************************************
- */
-
- #if defined(X11) || defined(AMIGA)
- /* This information used to define Astrolog's X icon (Rainbow over Third */
- /* Eye) is identical to the output format used by the bitmap program. */
- /* You could extract this section and run xsetroot -bitmap on it. */
-
- #define icon_width 63
- #define icon_height 32
-
- static
-
- #ifdef _DCC
- __chip
- #endif
-
- char icon_bits[] = {
- 0x00,0x00,0x00,0xa8,0x0a,0x00,0x00,0x00,
- 0x00,0x00,0x40,0x55,0x55,0x01,0x00,0x00,
- 0x00,0x00,0xa8,0xaa,0xaa,0x0a,0x00,0x00,
- 0x00,0x00,0x54,0xf5,0x57,0x15,0x00,0x00,
- 0x00,0x80,0xaa,0xaa,0xaa,0xaa,0x00,0x00,
- 0x00,0x40,0xd5,0xff,0xff,0x55,0x01,0x00,
- 0x00,0xa0,0xaa,0xaa,0xaa,0xaa,0x02,0x00,
- 0x00,0x50,0xfd,0xff,0xff,0x5f,0x05,0x00,
- 0x00,0xa8,0xaa,0x2a,0xaa,0xaa,0x0a,0x00,
- 0x00,0xd4,0xff,0xaf,0xfa,0xff,0x15,0x00,
- 0x00,0xaa,0x2a,0x00,0x00,0xaa,0x2a,0x00,
- 0x00,0xf5,0xbf,0xaa,0xaa,0xfe,0x57,0x00,
- 0x80,0xaa,0x02,0x00,0x00,0xa0,0xaa,0x00,
- 0x40,0xfd,0xab,0xfa,0xaf,0xea,0x5f,0x01,
- 0xa0,0xaa,0x80,0xff,0xff,0x80,0xaa,0x02,
- 0x50,0xff,0xea,0xff,0xff,0xab,0x7f,0x05,
- 0xa0,0x2a,0xf0,0xff,0xff,0x07,0xaa,0x02,
- 0xd0,0xbf,0xfa,0x0f,0xf8,0xaf,0x7e,0x05,
- 0xa8,0x0a,0xfc,0x01,0xc0,0x1f,0xa8,0x0a,
- 0xd4,0xaf,0x7e,0x00,0x00,0xbf,0xfa,0x15,
- 0xa8,0x0a,0x3f,0x00,0x00,0x7e,0xa8,0x0a,
- 0xf4,0xaf,0x1f,0xe0,0x03,0xfc,0xfa,0x15,
- 0xaa,0x82,0x0f,0xdc,0x1d,0xf8,0xa0,0x2a,
- 0xf4,0xab,0x07,0x23,0x62,0xf0,0xea,0x17,
- 0xaa,0xc2,0x87,0x91,0xc4,0xf0,0xa1,0x2a,
- 0xf4,0xeb,0xc3,0xd0,0x85,0xe1,0xeb,0x17,
- 0xaa,0xe0,0x83,0x91,0xc4,0xe0,0x83,0x2a,
- 0xf5,0xeb,0x03,0x23,0x62,0xe0,0xeb,0x57,
- 0xaa,0xe0,0x01,0xdc,0x1d,0xc0,0x83,0x2a,
- 0xf5,0xeb,0x01,0xe0,0x03,0xc0,0xeb,0x57,
- 0xaa,0xe0,0x01,0x00,0x00,0xc0,0x83,0x2a,
- 0xfd,0xeb,0x01,0x00,0x00,0xc0,0xeb,0x5f };
-
- #ifdef AMIGA
- struct Image icon_image = {
- 0, /* LeftEdge */
- 0, /* TopEdge */
- 63, /* Width */
- 32, /* Height */
- 1, /* Depth */
- &icon_bits[0], /* ImageData */
- 0x01, /* PlanePick */
- 0x00, /* PlaneOnOff */
- NULL /* NextImage */
- };
- #endif /* AMIGA */
-
- #endif /* X11 || AMIGA */
-
- /*
- ******************************************************************************
- ** Interactive Screen Graphics Routines.
- ******************************************************************************
- */
-
- /* Set up all the colors used by the program, i.e. the foreground and */
- /* background colors, and all the colors in the object arrays, based on */
- /* whether or not we are in monochrome and/or reverse video mode. */
-
- void InitColorsX()
- {
- int i;
-
- #ifdef X11
- Colormap cmap;
- XColor xcol;
-
- if (!gi.fFile) {
- cmap = XDefaultColormap(gi.disp, gi.screen);
-
- /* Allocate a color from the present X11 colormap. Given a string like */
- /* "violet", allocate this color and return a value specifying it. */
-
- for (i = 0; i < 16; i++)
- {
- XParseColor(gi.disp, cmap, szColorX[i], &xcol);
- XAllocColor(gi.disp, cmap, &xcol);
- rgbind[i] = xcol.pixel;
- }
- }
- #endif
-
- /* tf: corrected integer arithmetics with booleans: TRUE does not neccessarily be +1 !! */
-
- gi.kiOn = kMainA[ (!gs.fInverse) ? 1:0 ]; /*kMainA[!gs.fInverse];*/
- gi.kiOff = kMainA[gs.fInverse ? 1:0];
- gi.kiLite = gs.fColor ? kMainA[2+ (gs.fInverse ? 1:0)] : gi.kiOn;
- gi.kiGray = gs.fColor ? kMainA[3- (gs.fInverse ? 1:0)] : gi.kiOn;
-
- for (i = 0; i <= 8; i++) kMainB[i] = gs.fColor ? kMainA[i] : gi.kiOn;
- for (i = 0; i <= 7; i++) kRainbowB[i] = gs.fColor ? kRainbowA[i] : gi.kiOn;
- for (i = 0; i < 4; i++) kElemB[i] = gs.fColor ? kElemA[i] : gi.kiOn;
- for (i = 0; i <= cAspect; i++) kAspB[i] = gs.fColor ? kAspA[i] : gi.kiOn;
- for (i = 0; i <= cObj; i++) kObjB[i] = gs.fColor ? kObjA[i] : gi.kiOn;
-
- #if 0 /* debug */
- printf("kMainB[]\n"); for (i = 0; i <= 8; i++) printf("\t%d\n",kMainB[i]);
- printf("kRainbowB[]\n"); for (i = 0; i <= 7; i++) printf("\t%d\n",kRainbowB[i]);
- printf("kElemB[]\n"); for (i = 0; i < 4; i++) printf("\t%d\n",kElemB[i]);
- printf("kAspB[]\n"); for (i = 0; i <= cAspect; i++) printf("\t%d\n",kAspB[i]);
- printf("kObjB[]\n"); for (i = 0; i <= cObj; i++) printf("\t%d\n",kObjB[i]);
- #endif
-
- #ifdef X11
- if (!gi.fFile)
- {
- XSetBackground(gi.disp, gi.gc, rgbind[gi.kiOff]);
- XSetForeground(gi.disp, gi.pmgc, rgbind[gi.kiOff]);
- }
- #endif
- }
-
-
- #ifdef ISG
- /* This routine opens up and initializes a window and prepares it to be */
- /* drawn upon, and gets various information about the display, too. */
-
- void BeginX()
- {
-
- #ifdef X11
- gi.disp = XOpenDisplay(gs.szDisplay);
-
- if (gi.disp == NULL)
- {
- PrintError("Can't open display.");
- Terminate(tcFatal);
- }
-
- gi.screen = DefaultScreen(gi.disp);
-
- bg = BlackPixel(gi.disp, gi.screen);
- fg = WhitePixel(gi.disp, gi.screen);
-
- hint.x = gi.xOffset;
- hint.y = gi.yOffset;
-
- hint.width = gs.xWin;
- hint.height = gs.yWin;
-
- hint.min_width = BITMAPX1; hint.min_height = BITMAPY1;
- hint.max_width = BITMAPX; hint.max_height = BITMAPY;
-
- hint.flags = PPosition | PSize | PMaxSize | PMinSize;
-
- #if FALSE
- wmhint = XGetWMHints(gi.disp, gi.wind);
- wmhint->input = True;
- XSetWMHints(gi.disp, gi.wind, wmhint);
- #endif
-
- gi.depth = DefaultDepth(gi.disp, gi.screen);
-
- if (gi.depth < 5)
- {
- gi.fMono = fTrue; /* Is this a monochrome monitor? */
- gs.fColor = fFalse;
- }
-
- gi.root = RootWindow(gi.disp, gi.screen);
-
- if (gs.fRoot)
- gi.wind = gi.root; /* If -XB in effect, we'll use the root window. */
-
- else
- gi.wind = XCreateSimpleWindow(gi.disp, DefaultRootWindow(gi.disp),
- hint.x, hint.y, hint.width, hint.height, 5, fg, bg);
-
- gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
- gi.icon = XCreateBitmapFromData(gi.disp, DefaultRootWindow(gi.disp), icon_bits, icon_width, icon_height);
-
- if (!gs.fRoot)
- XSetStandardProperties(gi.disp, gi.wind, szAppName, szAppName, gi.icon, (char **)xkey, 0, &hint);
-
- /* We have two graphics workareas. One is what the user currently sees in */
- /* the window, and the other is what we are currently drawing on. When */
- /* done, we can quickly copy this to the viewport for a smooth look. */
-
- gi.gc = XCreateGC(gi.disp, gi.wind, 0, 0);
-
- XSetGraphicsExposures(gi.disp, gi.gc, 0);
- gi.pmgc = XCreateGC(gi.disp, gi.wind, 0, 0);
-
- InitColorsX(); /* Go set up colors. */
-
- if (!gs.fRoot)
- XSelectInput(gi.disp, gi.wind, KeyPressMask | StructureNotifyMask
- | ExposureMask
- | ButtonPressMask
- | ButtonReleaseMask
- | ButtonMotionMask );
-
- XMapRaised(gi.disp, gi.wind);
- XSync(gi.disp, 0);
- XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
- #endif /* X11 */
-
- #ifdef MSG
- if (!FValidResmode(gi.nRes)) /* Initialize graphics mode to hi-res. */
- gi.nRes = gs.nResHi;
-
- _setvideomode(gi.nRes);
-
- if (_grstatus())
- {
- PrintError("Can't enter graphics mode.");
- Terminate(tcFatal);
- }
-
- _getvideoconfig((struct videoconfig far *) &gi.cfg);
-
- if (gi.cfg.numcolors < 16)
- {
- gi.fMono = fTrue;
- gs.fColor = fFalse;
- }
- _remapallpalette((long FAR *) rgb);
- _setactivepage(0);
- _setvisualpage(0);
- InitColorsX();
-
- #ifdef MOUSE
- MouseInit(xPcScreen, yPcScreen);
- #endif
-
- /* Make sure we reset textrows upon restart. */
- gs.nTextRows = abs(gs.nTextRows);
- #endif /* MSG */
-
- #ifdef BGI
- int i;
- static struct palettetype pal;
-
- if ( !FValidResmode(gi.nRes) ) /* Initialize graphics mode to hi-res. */
- gi.nRes = gs.nResHi;
-
- if (!gi.fLoaded)
- {
- registerfarbgidriver(ATT_driver_far); /* attf.obj */
- registerfarbgidriver(CGA_driver_far); /* cgaf.obj */
- registerfarbgidriver(EGAVGA_driver_far); /* egavgaf.obj */
- registerfarbgidriver(Herc_driver_far); /* hercf.obj */
- registerfarbgidriver(IBM8514_driver_far); /* ibm8514f.obj */
- registerfarbgidriver(PC3270_driver_far); /* pc3270f.obj */
- gi.nDriver = DETECT;
- initgraph(&gi.nDriver, &gi.nGraph, "");
- gi.fLoaded = fTrue;
- }
-
- if (gi.nRes <= 0) {
- switch (gi.nDriver) {
- case CGA: gi.nGraph = CGAHI; break;
- case MCGA: gi.nGraph = MCGAHI; break;
- case EGA: gi.nGraph = EGAHI; break;
- case EGA64: gi.nGraph = EGA64HI; break;
- case EGAMONO: gi.nGraph = EGAMONOHI; break;
- case HERCMONO: gi.nGraph = HERCMONOHI; break;
- case ATT400: gi.nGraph = ATT400HI; break;
- case VGA: gi.nGraph = VGAHI; break;
- case PC3270: gi.nGraph = PC3270HI; break;
- case IBM8514: gi.nGraph = IBM8514HI; break;
- default: gi.nGraph = 0;
- }
- }
- else /* gi.nRes > 0 */
- {
- switch (gi.nDriver) {
- case CGA: gi.nGraph = CGAHI; break;
- case MCGA: gi.nGraph = MCGAHI; break;
- case EGA: gi.nGraph = EGAHI; break;
- case EGA64: gi.nGraph = EGA64HI; break;
- case EGAMONO: gi.nGraph = EGAMONOHI; break;
- case HERCMONO: gi.nGraph = HERCMONOHI; break;
- case ATT400: gi.nGraph = ATT400HI; break;
- case VGA: gi.nGraph = VGAMED; break;
- case PC3270: gi.nGraph = PC3270HI; break;
- case IBM8514: gi.nGraph = IBM8514LO; break;
- default: gi.nGraph = 0;
- }
- }
-
- setgraphmode(gi.nGraph);
-
- if( graphresult() )
- {
- PrintError("Can't enter graphics mode.");
- Terminate(tcFatal);
- }
-
- gi.nPages = 1 + (gi.nDriver == HERCMONO || (gi.nDriver == VGA && gi.nGraph != VGAHI) || gi.nDriver == EGA);
-
- if (getmaxcolor()+1 < 16)
- {
- gi.fMono = fTrue;
- gs.fColor = fFalse;
- }
- getpalette(&pal);
-
- for (i = 0; i < pal.size; i++)
- pal.colors[i] = (char)rgb[i];
-
- setallpalette(&pal);
- setactivepage(0);
- setvisualpage(0);
- gi.nPageCur = 0;
- InitColorsX();
-
- #ifdef MOUSE
- MouseInit(xPcScreen, yPcScreen);
- #endif
-
- /* Make sure we reset textrows upon restart. */
- gs.nTextRows = abs(gs.nTextRows);
-
- #endif /* BGI */
-
- #ifdef AMIGA
- if( AmigaDisplayInit() )
- {
- AmigaDisplayExit();
- PrintError("Can't open display.");
- Terminate(tcFatal);
- }
- InitColorsX();
- #endif /* AMIGA */
- }
-
-
- /* Add a certain amount of time to the current hour/day/month/year quantity */
- /* defining the present chart. This is used by the chart animation feature. */
- /* We can add or subtract anywhere from 1 to 9 seconds, minutes, hours, */
- /* days, months, years, decades, centuries, or millenia in any one call. */
- /* This is mainly just addition to the appropriate quantity, but we have */
- /* to check for overflows, e.g. Dec 30 + 3 days = Jan 2 of Current year + 1 */
-
- void AddTime(mode, toadd)
- int mode, toadd;
- {
- int d;
- real h, m;
-
- if ( !FBetween(mode, 1, 9) )
- mode = 4;
-
- h = RFloor(TT);
- m = RFract(TT)*100.0;
-
- if (mode == 1) m += 1.0/60.0*(real)toadd; /* Add seconds. */
- else if (mode == 2) m += (real)toadd; /* add minutes. */
-
- /* Add hours, either naturally or if minute value overflowed. */
-
- if (m < 0.0 || m >= 60.0 || mode == 3)
- {
- if (m >= 60.0)
- {
- m -= 60.0; toadd = NSgn(toadd);
- }
- else if (m < 0.0)
- {
- m += 60.0; toadd = NSgn(toadd);
- }
- h += (real)toadd;
- }
-
- /* Add days, either naturally or if hour value overflowed. */
-
- if (h >= 24.0 || h < 0.0 || mode == 4)
- {
- if (h >= 24.0)
- {
- h -= 24.0; toadd = NSgn(toadd);
- }
- else if (h < 0.0)
- {
- h += 24.0; toadd = NSgn(toadd);
- }
- DD = AddDay(MM, DD, YY, toadd);
- }
-
- /* Add months, either naturally or if day value overflowed. */
-
- if (DD > (d = DayInMonth(MM, YY)) || DD < 1 || mode == 5) {
- if (DD > d)
- {
- DD -= d; toadd = NSgn(toadd);
- }
- else if (DD < 1)
- {
- DD += DayInMonth(Mod12(MM - 1), YY);
- toadd = NSgn(toadd);
- }
- MM += toadd;
- }
-
- /* Add years, either naturally or if month value overflowed. */
-
- if (MM > 12 || MM < 1 || mode == 6)
- {
- if (MM > 12)
- {
- MM -= 12; toadd = NSgn(toadd);
- }
-
- else if (MM < 1)
- {
- MM += 12; toadd = NSgn(toadd);
- }
- YY += toadd;
- }
-
- if (mode == 7)
- YY += 10 * toadd; /* Add decades. */
-
- else if (mode == 8)
- YY += 100 * toadd; /* Add centuries. */
-
- else if (mode == 9)
- YY += 1000 * toadd; /* Add millenia. */
-
- TT = h+m/100.0; /* Recalibrate hour time. */
- }
-
-
- /* Animate the current chart based on the given values indicating how much */
- /* to update by. We update and recast the current chart info appropriately. */
-
- void Animate(mode, toadd)
- int mode, toadd;
- {
- if (gi.nMode == gWorldMap || gi.nMode == gGlobe || gi.nMode == gPolar)
- {
- gs.nRot += toadd;
-
- if (gs.nRot >= nDegMax) /* For animating globe display, add */
- gs.nRot -= nDegMax; /* in appropriate degree value. */
- else if (gs.nRot < 0)
- gs.nRot += nDegMax;
- }
- else
- {
- if (mode == 10)
- {
- #ifdef TIME
- /* For the continuous chart update to present moment */
- /* animation mode, go get whatever time it is now. */
- FInputData(szNowCore);
- #else
- ciCore = ciMain;
- AddTime(1, toadd);
- #endif
- }
- else /* Otherwise add on appropriate time vector to chart info. */
- {
- ciCore = ciMain;
- AddTime(mode, toadd);
- }
- ciMain = ciCore;
-
- if (us.nRel)
- CastRelation(fFalse);
- else
- CastChart(fTrue);
- }
- }
-
-
- /* This routine exits graphics mode, prompts the user for a set of command */
- /* switches, processes them, and returns to the previous graphics with the */
- /* new settings in effect, allowing one to change most any setting without */
- /* having to lose their graphics state or fall way back to a -Q loop. */
-
- void CommandLineX()
- {
- char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
- int argc, fT, fPause = fFalse;
-
- ciCore = ciMain;
-
- #ifdef MSG
- _setvideomode(_DEFAULTMODE);
- _settextrows(gs.nTextRows);
- #endif
-
- #ifdef BGI
- restorecrtmode();
- if (gs.nTextRows > 25)
- textmode(C4350);
- #endif
-
- #ifdef AMIGA
- EndX();
- #endif /* AMIGA */
-
- fT = us.fLoop; us.fLoop = fTrue;
- argc = NPromptSwitches(szCommandLine, rgsz);
- is.cchRow = 0;
- is.fSzInteract = fTrue;
-
- if (!FProcessSwitches(argc, rgsz))
- fPause = fTrue;
-
- else
- {
- is.fMult = fFalse;
- FPrintTables();
-
- if (is.fMult)
- {
- ClearB((lpbyte)&us.fCredit,
- (int)((lpbyte)&us.fLoop - (lpbyte)&us.fCredit));
- fPause = fTrue;
- }
- }
-
- #if defined(PCG) || defined(AMIGA)
-
- /* Pause for the user if there was either an error processing the */
- /* switches, or one of the informational text tables was brought up. */
-
- if(fPause)
- {
- AnsiColor(kDefault);
- is.cchRow = 0;
- PrintSz("Press any key to return to graphics.\n");
-
- #ifdef PCG
- while (!kbhit())
- ;
- getch();
- #endif
-
- #ifdef AMIGA
- (void)getkey();
- #endif
- }
- #endif
-
- is.fSzInteract = fFalse;
- us.fLoop = fT;
- ciMain = ciCore;
- BeginX();
- }
-
-
- /* Given two chart size values, adjust them such that the chart will look */
- /* "square". We round the higher value down and check certain conditions. */
-
- void SquareX(x, y, force)
- int *x, *y, force;
- {
- if (!force && !fSquare) /* Unless we want to force a square, realize */
- return; /* that some charts look better rectangular. */
- if (*x > *y)
- *x = *y;
- else
- *y = *x;
-
- #ifdef PCG
- if (FEgaRes(gi.nRes)) /* Scale horizontal size if we're in a PC */
- *x = VgaFromEga(*x); /* graphics mode without "square" pixels. */
- else if (FCgaRes(gi.nRes))
- *x = VgaFromCga(*x);
- #endif
-
- if (fSidebar) /* Take into account chart's sidebar, if any. */
- *x += xSideT;
- }
-
-
- /* This routine gets called after graphics are brought up and displayed */
- /* on the screen. It loops, processing key presses, mouse clicks, etc, that */
- /* the window receives, until the user specifies they want to exit program. */
-
- void InteractX()
- {
- #ifdef X11
- char sz[cchSzDef];
- XEvent xevent;
- KeySym keysym;
- int fResize = fFalse, fRedraw = fTrue;
- #endif
-
- #ifdef PCG
- #ifdef MOUSE
- int eventx, eventy, eventbtn;
- #endif
- int fResize = fTrue, fRedraw = fFalse;
- #endif /* PCG */
-
- #ifdef AMIGA
- int fResize = fFalse, fRedraw = fTrue;
- int fMouseDown= fFalse;
-
- /*
- * Since some chart windows need a certain size, we have save the initial
- * window dimensions. This might be a general astrolog problem, however I
- * fixed it for Amiga only since I'm not sure.
- */
-
- int gs_xWin= gs.xWin,
- gs_yWin= gs.yWin;
- #endif
-
- int fBreak = fFalse,
- fPause = fFalse,
- fCast = fFalse,
- xcorner = 7,
- mousex = -1,
- mousey = -1,
- buttonx = -1,
- buttony = -1,
- dir = 1,
- length, key, i;
-
- bool fT;
- KI coldrw = gi.kiLite;
-
- neg(gs.nAnim);
-
- /*
- * interaction loop
- */
-
- while (!fBreak)
- {
-
- #ifdef AMIGA
- if(gs.xWin != gs_xWin) { gs.xWin= gs_xWin; fResize= fTrue; }
- if(gs.yWin != gs_yWin) { gs.yWin= gs_yWin; fResize= fTrue; }
- #endif
-
- gi.nScale = gs.nScale/100;
-
- /* Some chart windows, like the world maps and aspect grids, should */
- /* always be a certian size, so correct if a resize was attempted. */
-
- if (fMap)
- {
- length = nDegMax * gi.nScale;
-
- if (gs.xWin != length)
- {
- gs.xWin = length;
- fResize = fTrue;
- }
-
- length = nDegHalf*gi.nScale;
-
- if (gs.yWin != length)
- {
- gs.yWin = length;
- fResize = fTrue;
- }
- }
-
- else if (gi.nMode == gGrid)
- {
- if (gs.xWin !=
- (length = (gs.nGridCell + (us.nRel <= rcDual)) * CELLSIZE*gi.nScale+1))
- {
- gs.xWin = length;
- fResize = fTrue;
- }
-
- if (gs.yWin != length)
- {
- gs.yWin = length;
- fResize = fTrue;
- }
- }
-
- /* Make sure the window isn't too large or too small. */
-
- else
- {
- if (gs.xWin < BITMAPX1)
- {
- gs.xWin = BITMAPX1;
- fResize = fTrue;
- }
-
- else if (gs.xWin > BITMAPX)
- {
- gs.xWin = BITMAPX;
- fResize = fTrue;
- }
-
- if (gs.yWin < BITMAPY1)
- {
- gs.yWin = BITMAPY1;
- fResize = fTrue;
- }
- else if (gs.yWin > BITMAPY)
- {
- gs.yWin = BITMAPY;
- fResize = fTrue;
- }
- }
-
- /* If in animation mode, ensure we are in the flicker free resolution. */
-
- if (gs.nAnim < 0)
- {
- neg(gs.nAnim);
-
- #ifdef PCG
- if (gi.nRes == gs.nResHi && !gs.fJetTrail)
- {
- gi.nRes = gs.nResLo;
- BeginX();
- gs.xWin = xPcScreen;
- gs.yWin = yPcScreen;
- SquareX(&gs.xWin, &gs.yWin, fFalse);
- fResize = fTrue;
- }
- #endif
- }
-
- #ifdef AMIGA
- /* toggle double buffering depending on `gs.nAnim' */
-
- if( (gs.nAnim && !gi.paging) || (!gs.nAnim && gi.paging) )
- AmigaDisplayPaging();
- #endif
-
- /* Physically resize window if we've changed the size parameters. */
-
- if (fResize)
- {
- fResize = fFalse;
-
- #ifdef X11
- XResizeWindow(gi.disp, gi.wind, gs.xWin, gs.yWin);
- XFreePixmap(gi.disp, gi.pmap);
- gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
- #endif
-
- #ifdef PCG
- if (xPcScreen > gs.xWin)
- gi.xOffset = (xPcScreen - gs.xWin) / 2;
-
- else
- {
- if (xcorner % 3 == 1)
- gi.xOffset = 0;
- else if (xcorner % 3 == 0)
- gi.xOffset = -gs.xWin + xPcScreen;
- else
- gi.xOffset = -(gs.xWin - xPcScreen) / 2;
- }
-
- if (yPcScreen > gs.yWin)
- gi.yOffset = (yPcScreen - gs.yWin) / 2;
-
- else
- {
- if (xcorner > 6)
- gi.yOffset = 0;
- else if (xcorner < 4)
- gi.yOffset = -gs.yWin + yPcScreen;
- else
- gi.yOffset = -(gs.yWin - yPcScreen) / 2;
- }
- #endif /* PCG */
-
- #ifdef AMIGA
- if( AmigaDisplayResize(gs.xWin, gs.yWin) != 0 )
- {
- PrintError("Can't resize display.");
- Terminate(tcFatal);
- fBreak= fTrue;
- break;
- }
- #endif /* AMIGA */
-
-
- fRedraw = fTrue;
- }
-
- /* Recast chart if the chart information has changed any. */
-
- if (fCast)
- {
- fCast = fFalse;
- ciCore = ciMain;
-
- if (us.nRel)
- CastRelation(fFalse);
- else
- CastChart(fTrue);
-
- fRedraw = fTrue;
- }
-
- if (gs.nAnim && !fPause)
- fRedraw = fTrue;
-
- /* Update the screen if anything has changed since last time around. */
-
- if (fRedraw)
- {
- fRedraw = fFalse;
-
- /* If we're in animation mode, change the chart info appropriately. */
-
- if (gs.nAnim && !fPause)
- Animate(gs.nAnim, dir);
-
- /* Clear the screen and set up a buffer to draw in. */
-
- #ifdef X11
- XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
- #endif
-
-
- #ifdef PCG
-
- #if defined(PC) && defined(MOUSE)
- MouseShow(fFalse);
- #endif /* PC & MOUSE */
-
- #ifdef MSG
- if (gi.cfg.numvideopages > 1)
- _setactivepage(_getactivepage() == gs.fJetTrail);
-
- #else /* !MSG */
- if (gi.nPages > 1)
- {
- gi.nPageCur = (gi.nPageCur == gs.fJetTrail);
- setactivepage(gi.nPageCur);
- }
- #endif /* MSG */
-
- #endif /* PCG */
-
- #ifdef AMIGA
- if(!gs.fJetTrail)
- AmigaClearScreen();
- #endif /* AMIGA */
-
- DrawChartX();
-
- /* Make the drawn chart visible in the current screen buffer. */
-
- #ifdef X11
- XSync(gi.disp, 0);
- XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0);
- #else /* PCG */
-
- #ifdef MSG
- if (gi.cfg.numvideopages > 1)
- _setvisualpage(_getactivepage());
- #endif /* MSG */
-
-
- #ifdef PCG
- if (gi.nPages > 1)
- setvisualpage(gi.nPageCur);
- #endif /* PCG */
-
- #if defined(PC) && defined(MOUSE)
- if (!gs.nAnim || fPause)
- MouseShow(fTrue);
- #endif /* PC && MOUSE */
-
- #endif /* PCG */
-
- #ifdef AMIGA
- AmigaDisplayUpdate();
- #endif /* AMIGA */
-
- } /* fRedraw */
-
- /* Now process what's on the event queue, i.e. any keys pressed, etc. */
-
- #ifdef X11
- if (XEventsQueued(gi.disp, QueuedAfterFlush /*QueuedAfterReading*/) || !gs.nAnim || fPause)
- {
- XNextEvent(gi.disp, &xevent);
-
- /* Restore what's on window if a part of it gets uncovered. */
-
- if (xevent.type == Expose && xevent.xexpose.count == 0)
- {
- XSync(gi.disp, 0);
- XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0);
- }
- switch (xevent.type) {
-
- /* Check for a manual resize of window by user. */
-
- case ConfigureNotify:
- gs.xWin = xevent.xconfigure.width;
- gs.yWin = xevent.xconfigure.height;
- XFreePixmap(gi.disp, gi.pmap);
- gi.pmap = XCreatePixmap(gi.disp, gi.wind, gs.xWin, gs.yWin, gi.depth);
- fRedraw = fTrue;
- break;
-
- case MappingNotify:
- XRefreshKeyboardMapping((XMappingEvent *)&xevent);
- break;
-
- #ifdef MOUSE
- /* Process any mouse buttons the user pressed. */
-
- case ButtonPress:
- mousex = xevent.xbutton.x; mousey = xevent.xbutton.y;
-
- if (xevent.xbutton.button == Button1)
- {
- DrawColor(gi.kiLite);
- DrawPoint(mousex, mousey);
- XSync(gi.disp, 0);
- XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0);
- }
- else if(xevent.xbutton.button == Button2 &&
- (gi.nMode == gAstroGraph || gi.nMode == gWorldMap) && gs.nRot == 0)
- {
- Lon = DegToDec(rDegHalf - (real)(xevent.xbutton.x-1)/(real)(gs.xWin-2)*rDegMax);
- Lat = DegToDec(rDegQuad - (real)(xevent.xbutton.y-1)/(real)(gs.yWin-2)*181.0);
- sprintf(sz, "Mouse is at %s.", SzLocation(Lon, Lat));
- PrintNotice(sz);
- }
- else if (xevent.xbutton.button == Button3)
- fBreak = fTrue;
- break;
-
- /* Check for user dragging any of the mouse buttons across window. */
-
- case MotionNotify:
- DrawColor(coldrw);
- DrawLine(mousex, mousey, xevent.xbutton.x, xevent.xbutton.y);
- XSync(gi.disp, 0);
- XCopyArea(gi.disp, gi.pmap, gi.wind, gi.gc, 0, 0, gs.xWin, gs.yWin, 0, 0);
- mousex = xevent.xbutton.x; mousey = xevent.xbutton.y;
- break;
-
- #endif /* MOUSE */
-
- /* Process any keys user pressed in window. */
-
- case KeyPress:
- length = XLookupString((XKeyEvent *)&xevent, xkey, 10, &keysym, 0);
- if (length == 1) {
- key = xkey[0];
-
- #endif /* X11 */
-
- /*
- * Get events on PC
- */
-
- #ifdef PCG
- #ifdef MOUSE
- if ((!gs.nAnim || fPause) && MouseStatus(&eventx, &eventy, &eventbtn))
- {
- /* If the left button is down, draw on the screen. */
-
- if (eventbtn == mfLeft && mousex >= 0)
- {
- MouseShow(fFalse);
- DrawColor(coldrw);
- PcMoveTo(mousex, mousey);
- buttonx = eventx; buttony = eventy;
- PcLineTo(buttonx, buttony);
- }
-
- /* If the right button is down, change the default location. */
-
- else if (eventbtn == mfRight)
- {
- if (fMap && gs.nRot == 0 && !gs.fConstel && !gs.fMollewide)
- {
- Lon = rDegHalf-(real)(eventx-gi.xOffset)/(real)(gs.xWin-2)*rDegMax;
-
- if (Lon < -rDegHalf) Lon = -rDegHalf;
- else if (Lon > rDegHalf) Lon = rDegHalf;
-
- Lat = rDegQuad-(real)(eventy-gi.yOffset)/(real)(gs.yWin-2)*181.0;
-
- if (Lat < -rDegQuad) Lat = -rDegQuad;
- else if (Lat > rDegQuad) Lat = rDegQuad;
-
- fCast = fTrue;
- }
-
- /* Right button means draw lines if not in a world map mode. */
-
- else if (buttonx >= 0)
- {
- MouseShow(fFalse);
- DrawColor(coldrw);
- PcMoveTo(buttonx, buttony);
- PcLineTo(eventx, eventy);
- }
- }
-
- /* Middle button (which most PC's don't have) means exit program. */
-
- else if (eventbtn == mfMiddle)
- fBreak = fTrue;
-
- mousex = eventx; mousey = eventy;
- MouseShow(fTrue);
- } else
- #endif /* MOUSE */
-
- if (kbhit())
- {
- key = getch();
-
- #endif /* PCG */
-
- /*
- * Get events on Amiga systems
- */
-
- #ifdef AMIGA
-
- #ifdef MUIGUI
- key= AmigaDisplayInteract();
-
- #else /* MUIGUI */
-
- /*{ key = getkey();*/
-
- key= '\0'; /* undefined = no keypress */
-
- {
- struct Window *w= gi.win;
- struct IntuiMessage *imsg;
- ULONG class;
- USHORT code;
-
- /* as long as we don't have any events to export... */
-
- while( (key=='\0') && !fBreak && !fResize )
- {
- ULONG sig= Wait( SIGBREAKF_CTRL_C | (1L<<w->UserPort->mp_SigBit) );
-
- if( sig & SIGBREAKF_CTRL_C )
- fBreak= fTrue;
-
- if( sig & (1L<<w->UserPort->mp_SigBit) )
- while( (imsg=(struct IntuiMessage *)GetMsg(w->UserPort)) )
- {
- class = imsg->Class;
- code = imsg->Code;
-
- mousex = (int)(imsg->MouseX);
- mousey = (int)(imsg->MouseY);
-
- ReplyMsg((struct Message *)imsg);
-
- switch(class)
- {
- case CLOSEWINDOW:
- fBreak= fTrue;
- fMouseDown= fFalse;
- break;
-
- case VANILLAKEY:
- /* the key code is handled at label LSwitch: */
-
- key= (int)code;
- fMouseDown= fFalse;
- break;
-
- case MOUSEBUTTONS:
- if(code==SELECTDOWN)
- {
- buttonx= mousex;
- buttony= mousey;
-
- DrawColor(coldrw);
- DrawPoint(mousex,mousey);
-
- fMouseDown= fTrue;
- }
- else if(code==SELECTUP) /* well, what else can it be? */
- {
- fMouseDown= fFalse;
- }
- break;
-
- case MOUSEMOVE:
- /* we already initialized mousex and mousey */
-
- if(fMouseDown==fTrue)
- {
- DrawColor(coldrw);
- DrawPoint(mousex,mousey);
- }
- break;
-
- case NEWSIZE:
- {
- int xmin= (int)(w->BorderLeft);
- int ymin= (int)(w->BorderTop);
- int xmax= (int)(w->Width - w->BorderRight - 1);
- int ymax= (int)(w->Height - w->BorderBottom - 1);
-
- gi.xOffset = xmin;
- gi.yOffset = ymin;
-
- gs.xWin = xmax - xmin;
- gs.yWin = ymax - ymin;
-
- /* Now we _really_ want to resize */
- gs_xWin = gs.xWin; gs_yWin = gs.yWin;
- }
- fMouseDown= fFalse;
- fResize= fTrue;
- break;
-
- case INTUITICKS:
- /*if(!gs.nAnim)
- ModifyIDCMP(w, (w->IDCMPFlags) & ~INTUITICKS);*/
- break;
- }
- }
-
- if(gs.nAnim)
- break;
- }
- }
- #endif /* !MUIGUI */
-
- if(key != '\0')
- {
- #endif /* AMIGA */
-
-
- /*
- * Handle keyboard input
- */
-
- LSwitch:
- switch (key) {
- #ifdef PCG
- case chNull:
- key = NFromAltN(getch());
- goto LSwitch;
- #endif
- case ' ':
- fRedraw = fTrue;
- break;
- case 'p':
- not(fPause);
- break;
- case 'r':
- neg(dir);
- break;
- case 'x':
- not(gs.fInverse);
- InitColorsX();
- fRedraw = fTrue;
- break;
- case 'm':
- if (!gi.fMono)
- {
- not(gs.fColor);
- #ifdef MSG
- _getvideoconfig((struct videoconfig far *) &gi.cfg);
- #endif
- InitColorsX();
- fRedraw = fTrue;
- }
- break;
- case 'B':
- #ifdef X11
- XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
- XClearWindow(gi.disp, gi.root);
- #endif
-
- #ifdef PCG
- gs.xWin = xPcScreen;
- gs.yWin = yPcScreen;
- SquareX(&gs.xWin, &gs.yWin, fFalse);
- fResize = fTrue;
- #endif
- break;
- case 't':
- not(gs.fText);
- fRedraw = fTrue;
- break;
- case 'i':
- not(gs.fAlt);
- fRedraw = fTrue;
- break;
- case 'b':
- not(gs.fBorder);
- fRedraw = fTrue;
- break;
- case 'l':
- not(gs.fLabel);
- fRedraw = fTrue;
- break;
- case 'j':
- not(gs.fJetTrail);
- break;
- case '<':
- if (gs.nScale > 100)
- {
- gs.nScale -= 100;
- fResize = fTrue;
- }
- break;
- case '>':
- if (gs.nScale < 400)
- {
- gs.nScale += 100;
- fResize = fTrue;
- }
- break;
- case '[':
- if (gi.nMode == gGlobe && gs.rTilt > -rDegQuad)
- {
- gs.rTilt = gs.rTilt > -rDegQuad ? gs.rTilt-11.25 : -rDegQuad;
- fRedraw = fTrue;
- }
- break;
- case ']':
- if (gi.nMode == gGlobe && gs.rTilt < rDegQuad)
- {
- gs.rTilt = gs.rTilt < rDegQuad ? gs.rTilt+11.25 : rDegQuad;
- fRedraw = fTrue;
- }
- break;
- case 'Q':
- SquareX(&gs.xWin, &gs.yWin, fTrue);
- fResize = fTrue;
- break;
- case 'R':
- for (i = oChi; i <= oVes; i++)
- not(ignore[i]);
- for (i = oLil; i <= oEP; i++)
- not(ignore[i]);
- fCast = fTrue;
- break;
- case 'C':
- not(us.fCusp);
- for (i = cuspLo; i <= cuspHi; i++)
- ignore[i] = !us.fCusp || !ignore[i];
- fCast = fTrue;
- break;
- case 'u':
- not(us.fUranian);
- for (i = uranLo; i <= uranHi; i++)
- ignore[i] = !us.fUranian || !ignore[i];
- fCast = fTrue;
- break;
- case 'U':
- us.nStar = !us.nStar;
- for (i = starLo; i <= starHi; i++)
- ignore[i] = !us.nStar || !ignore[i];
- fCast = fTrue;
- break;
- case 'c':
- if (!us.nRel)
- {
- us.nRel = rcDual;
- ciTwin = ciMain;
- }
- else us.nRel = 0;
- fCast = fTrue;
- break;
- case 's':
- not(us.fSiderial);
- fCast = fTrue;
- break;
- case 'h':
- us.objCenter = us.objCenter ? 0 : 1;
- fCast = fTrue;
- break;
- case 'f':
- not(us.fFlip);
- fCast = fTrue;
- break;
- case 'g':
- not(us.fDecan);
- fCast = fTrue;
- break;
- case '+':
- Animate(gs.nAnim, abs(dir));
- fCast = fTrue;
- break;
- case '-':
- Animate(gs.nAnim, -abs(dir));
- fCast = fTrue;
- break;
- case 'o':
- ciSave = ciMain;
- break;
- case 'O':
- ciMain = ciSave;
- fCast = fTrue;
- break;
-
- #ifdef TIME
- case 'n':
- FInputData(szNowCore);
- ciMain = ciCore;
- fCast = fTrue;
- break;
- #endif /* TIME */
-
- case 'N': /* The continuous update animation. */
- gs.nAnim = gs.nAnim ? 0 : -10;
- break;
-
- /* These are the nine different "add time to chart" animations. */
-
- case '!': gs.nAnim = -1; break;
- case '@': gs.nAnim = -2; break;
- case '#': gs.nAnim = -3; break;
- case '$': gs.nAnim = -4; break;
- case '%': gs.nAnim = -5; break;
- case '^': gs.nAnim = -6; break;
- case '&': gs.nAnim = -7; break;
- case '*': gs.nAnim = -8; break;
- case '(': gs.nAnim = -9; break;
-
- /* Should we go switch to a new chart type? */
-
- case 'V': gi.nMode = gWheel; fRedraw = fTrue; break;
- case 'A': gi.nMode = gGrid; fRedraw = fTrue; break;
- case 'Z': gi.nMode = gHorizon; fRedraw = fTrue; break;
- case 'S': gi.nMode = gOrbit; fRedraw = fTrue; break;
- case 'J': gi.nMode = gDisposit; fRedraw = fTrue; break;
- case 'L': gi.nMode = gAstroGraph; fRedraw = fTrue; break;
- case 'K': gi.nMode = gCalendar; fRedraw = fTrue; break;
- case 'E': gi.nMode = gEphemeris; fRedraw = fTrue; break;
- case 'W': gi.nMode = gWorldMap; fRedraw = fTrue; break;
- case 'G': gi.nMode = gGlobe; fRedraw = fTrue; break;
- case 'P': gi.nMode = gPolar; fRedraw = fTrue; break;
-
- #ifdef BIORHYTHM
- case 'Y': /* Should we switch to biorhythm chart? */
- if (!us.nRel)
- ciTwin = ciMain;
- us.nRel = rcBiorhythm;
- gi.nMode = gBiorhythm;
- fCast = fTrue;
- break;
- #endif /* BIORHYTHM */
-
-
- #ifdef CONSTEL
- case 'F':
- if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
- gi.nMode = gWorldMap;
- not(gs.fConstel);
- fRedraw = fTrue;
- break;
- #endif /* CONSTEL */
-
- case '0':
- not(us.fPrimeVert);
- not(us.fCalendarYear);
- not(us.nEphemYears);
- not(gs.fMollewide);
- gi.nMode = (gi.nMode == gWheel ? gHouse :
- (gi.nMode == gHouse ? gWheel : gi.nMode));
- fRedraw = fTrue;
- break;
- case 'v': case 'H': case '?':
-
- #ifdef MSG
- _setvideomode(_DEFAULTMODE);
- if (key != 'v')
- _settextrows(50);
- #endif /* MSG */
-
- #ifdef BGI
- restorecrtmode();
- if (key != 'v')
- textmode(C4350);
- #endif /* BGI */
-
- #ifdef AMIGA
- /*ScreenToBack(gi.scr);*/
-
- /*EndX();*/
- AmigaClearScreen(); xPrintAt(1,1,"");
- #endif /* AMIGA */
-
- length = us.nScrollRow;
- us.nScrollRow = 0;
- if (key == 'v')
- ChartListing();
- else
- DisplayKeysX();
- us.nScrollRow = length;
-
- #ifdef PCG
- while (!kbhit())
- ;
- key = getch();
- if (key == 'q' || key == chEscape || key == chBreak)
- {
- fBreak = fTrue;
- break;
- }
- BeginX();
- fResize = fTrue;
- #endif /* PCG */
-
- #ifdef AMIGA
- /*key= getkey();*/
- AmigaDisplayUpdate(); key= AmigaGetKey();
-
- if(key == 'q' || key == chEscape || key == chBreak)
- {
- fBreak= fTrue;
- break;
- }
- /*ScreenToFront(gi.scr);*/
- /*BeginX();*/
- fResize= fTrue;
- #endif /* AMIGA */
- break;
-
- case chReturn:
- CommandLineX();
- fResize = fCast = fTrue;
- break;
-
- #ifdef PCG
- case chTab:
- if (gi.nRes == gs.nResHi)
- gi.nRes = gs.nResLo;
- else
- gi.nRes = gs.nResHi;
- BeginX();
- gs.xWin = xPcScreen;
- gs.yWin = yPcScreen;
- SquareX(&gs.xWin, &gs.yWin, fFalse);
- fResize = fTrue;
- break;
- #endif /* PCG */
-
- #ifdef AMIGA
- case chTab:
- key= AmigaDisplayDebug();
- if(key == 'q' || key == chEscape || key == chBreak)
- fBreak= fTrue;
- fResize = fCast = fTrue;
- break;
- #endif
-
- case chDelete:
-
- #ifdef PCG
- #ifdef MOUSE
- MouseShow(fFalse);
- #endif
- #endif /* PCG */
-
- fT = gs.fJetTrail;
- gs.fJetTrail = fFalse;
- DrawClearScreen();
- gs.fJetTrail = fT;
- break;
-
- #ifdef MOUSE
- case 'z'-'`': coldrw = kBlack; break;
- case 'e'-'`': coldrw = kMaroon; break;
- case 'f'-'`': coldrw = kDkGreen; break;
- case 'o'-'`': coldrw = kOrange; break;
- case 'n'-'`': coldrw = kDkBlue; break;
- case 'u'-'`': coldrw = kPurple; break;
- case 'k'-'`': coldrw = kDkCyan; break;
- case 'l'-'`': coldrw = kLtGray; break;
- case 'd'-'`': coldrw = kDkGray; break;
- case 'r'-'`': coldrw = kRed; break;
- case 'g'-'`': coldrw = kGreen; break;
- case 'y'-'`': coldrw = kYellow; break;
- case 'b'-'`': coldrw = kBlue; break;
- case 'v'-'`': coldrw = kMagenta; break;
- case 'j'-'`': coldrw = kCyan; break;
- case 'a'-'`': coldrw = kWhite; break;
- #ifdef PCG
- case 't'-'`':
- MouseShow(fFalse);
- if (buttonx >= 0)
- #ifdef MSG
- _rectangle(_GBORDER, buttonx, buttony, mousex, mousey);
- #else
- DrawEdge(Min(buttonx, mousex) - gi.xOffset,
- Min(buttony, mousey) - gi.yOffset,
- Max(mousex, buttonx) - gi.xOffset,
- Max(mousey, buttony) - gi.yOffset);
- #endif /* MSG */
- MouseShow(fTrue);
- break;
- case 'x'-'`':
- MouseShow(fFalse);
- if (buttonx >= 0)
- {
- #ifdef MSG
- _ellipse(_GBORDER, buttonx, buttony, mousex, mousey);
- #else
- DrawEllipse(Min(buttonx, mousex) - gi.xOffset,
- Min(buttony, mousey) - gi.yOffset,
- Max(mousex, buttonx) - gi.xOffset,
- Max(mousey, buttony) - gi.yOffset);
- #endif /* MSG */
- }
- MouseShow(fTrue);
- break;
- #endif /* PCG */
- #endif /* MOUSE */
- case 'q': case chEscape: case chBreak:
- fBreak = fTrue;
- break;
- default:
- if (key > '0' && key <= '9')
- {
- #ifdef PCG
- if (gs.nAnim && !fPause)
- #endif /* PCG */
- /* Process numbers 1..9 signifying animation rate. */
- dir = (dir > 0 ? 1 : -1)*(key-'0');
- #ifdef PCG
- else
- {
- /* If we aren't in animation mode, then 1..9 refers to the */
- /* clipping "quadrant" to use if chart size > screen size. */
-
- xcorner = key-'0';
- fResize = fTrue;
- }
- #endif /* PCG */
-
- break;
- }
- else if (FBetween(key, 201, 248))
- {
- is.fSzInteract = fTrue;
- if (szMacro[key-201])
- {
- FProcessCommandLine(szMacro[key-201]);
- fResize = fCast = fTrue;
- }
- is.fSzInteract = fFalse;
- break;
- }
- putchar(chBell); /* Any key not bound will sound a beep. */
- } /* switch */
- } /* if */
-
- #ifdef X11
- default:
- ;
- } /* switch */
- } /* if */
- #endif /* X11 */
-
- } /* while */
- }
-
-
- /* This is called right before program termination to get rid of the window. */
-
- void EndX()
- {
- #ifdef X11
- XFreeGC(gi.disp, gi.gc);
- XFreeGC(gi.disp, gi.pmgc);
- XFreePixmap(gi.disp, gi.pmap);
- XDestroyWindow(gi.disp, gi.wind);
- XCloseDisplay(gi.disp);
- #endif
-
- #ifdef MSG
- _setvideomode(_DEFAULTMODE);
- #endif
-
- #ifdef BGI
- restorecrtmode();
- #endif
-
- #ifdef AMIGA
- AmigaDisplayExit();
- #endif
-
- }
- #endif /* ISG */
-
-
- /*
- ******************************************************************************
- ** Main Graphics Processing.
- ******************************************************************************
- */
-
- /* Process one command line switch passed to the program dealing with the */
- /* graphics features. This is just like the processing of each switch in the */
- /* main program, however here each switch has been prefixed with an 'X'. */
-
- int NProcessSwitchesX(argc, argv, pos, fOr, fAnd, fNot)
- int argc, pos;
- bool fOr, fAnd, fNot;
- char **argv;
- {
- int darg = 0, i, j;
- real rT;
- char ch1;
-
- ch1 = argv[0][pos+1];
-
- switch (argv[0][pos]) {
-
- case chNull:
- break;
-
- case 'b':
- /*printf("--> `Xb' switch detected!\n");*/
- if (is.fSzInteract)
- {
- ErrorArgv("Xb");
- return tcError;
- }
- ch1 = ChCap(ch1);
-
- if (FValidBmpmode(ch1))
- gs.chBmpMode = ch1;
-
- SwitchF2(gs.fBitmap);
- gs.fPS = gs.fMeta = fFalse;
- break;
-
- #ifdef PS
- case 'p':
- if (is.fSzInteract)
- {
- ErrorArgv("Xp");
- return tcError;
- }
- gs.fPS = fTrue + (ch1 != '0');
- gs.fBitmap = gs.fMeta = fFalse;
- break;
- #endif
-
- #ifdef META
- case 'M':
- if (is.fSzInteract)
- {
- ErrorArgv("XM");
- return tcError;
- }
- if (ch1 == '0')
- SwitchF(gs.fFont);
-
- SwitchF2(gs.fMeta);
- gs.fBitmap = gs.fPS = fFalse;
- break;
- #endif
-
- case 'o':
- if (is.fSzInteract)
- {
- ErrorArgv("Xo");
- return tcError;
- }
- if (argc <= 1)
- {
- ErrorArgc("Xo");
- return tcError;
- }
-
- if (!gs.fBitmap && !gs.fPS && !gs.fMeta)
- gs.fBitmap = fTrue; /* default */
-
- gi.szFileOut = SzPersist(argv[1]);
- darg++;
- break;
-
- #ifdef X11
- case 'B':
- if (is.fSzInteract)
- {
- ErrorArgv("XB");
- return tcError;
- }
- SwitchF(gs.fRoot);
- break;
- #endif
-
- case 'm':
- SwitchF(gs.fColor);
- break;
-
- case 'r':
- SwitchF(gs.fInverse);
- break;
-
- case 'w':
- if (argc <= 1)
- {
- ErrorArgc("Xw");
- return tcError;
- }
-
- i = atoi(argv[1]);
-
- if (argc > 2 && ((j = atoi(argv[2])) || argv[2][0] == '0'))
- {
- argc--; argv++;
- darg++;
- }
- else j = i;
-
- if (!FValidGraphx(i))
- {
- ErrorValN("Xw", i);
- return tcError;
- }
- if (!FValidGraphy(j))
- {
- ErrorValN("Xw", j);
- return tcError;
- }
- gs.xWin = i; gs.yWin = j;
- darg++;
- break;
-
- case 's':
- if (argc <= 1)
- {
- ErrorArgc("Xs");
- return tcError;
- }
- i = atoi(argv[1]);
- if (i < 100)
- i *= 100;
-
- if (!FValidScale(i))
- {
- ErrorValN("Xs", i);
- return tcError;
- }
- gs.nScale = i;
- darg++;
- break;
-
- case 'i':
- SwitchF(gs.fAlt);
- break;
-
- case 't':
- SwitchF(gs.fText);
- break;
-
- case 'u':
- SwitchF(gs.fBorder);
- break;
-
- case 'l':
- SwitchF(gs.fLabel);
- break;
-
- case 'j':
- SwitchF(gs.fJetTrail);
- break;
-
- case '1':
- if (argc <= 1)
- {
- ErrorArgc("X1");
- return tcError;
- }
- i = atoi(argv[1]);
- if (!FItem(i))
- {
- ErrorValN("X1", i);
- return tcError;
- }
- gs.nLeft = i;
- darg++;
- break;
-
- case '2':
- if (argc <= 1)
- {
- ErrorArgc("X2");
- return tcError;
- }
- i = atoi(argv[1]);
- if (!FItem(i)) {
- ErrorValN("X2", i);
- return tcError;
- }
- gs.nLeft = -i;
- darg++;
- break;
-
- case 'd':
- if (is.fSzInteract)
- {
- ErrorArgv("Xd");
- return tcError;
- }
- if (argc <= 1)
- {
- ErrorArgc("Xd");
- return tcError;
- }
- gs.szDisplay = SzPersist(argv[1]);
- darg++;
- break;
-
- case 'W':
- if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0'))
- {
- darg++;
- if (!FValidRotation(i))
- {
- ErrorValN("XW", i);
- return tcError;
- }
- gs.nRot = i;
- }
- gi.nMode = gWorldMap;
- if (ch1 == '0')
- gs.fMollewide = fTrue;
- is.fHaveInfo = fTrue;
- break;
-
- case 'G':
- if (argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0'))
- {
- darg++;
- if (!FValidRotation(i))
- {
- ErrorValN("XG", i);
- return tcError;
- }
- gs.nRot = i;
- if (argc > 2 && ((rT = atof(argv[2])) || argv[2][0] == '0'))
- {
- darg++;
- if (!FValidTilt(rT))
- {
- ErrorValR("XG", rT);
- return tcError;
- }
- gs.rTilt = rT;
- }
- }
- gi.nMode = gGlobe;
- is.fHaveInfo = fTrue;
- break;
-
- case 'P':
- if(argc > 1 && ((i = atoi(argv[1])) || argv[1][0] == '0'))
- {
- darg++;
- if (!FValidRotation(i))
- {
- ErrorValN("XP", i);
- return tcError;
- }
- }
- else i = 0;
- gs.nRot = i;
- gi.nMode = gPolar;
- if (ch1 == '0')
- gs.fPrintMap = fTrue;
- is.fHaveInfo = fTrue;
- break;
-
- #ifdef CONSTEL
- case 'F':
- if (!fMap && gi.nMode != gGlobe && gi.nMode != gPolar)
- gi.nMode = gWorldMap;
- not(gs.fConstel);
- is.fHaveInfo = fTrue;
- break;
- #endif
-
- #ifdef ISG
- case 'n':
- if (argc > 1 && (i = atoi(argv[1])))
- darg++;
- else
- i = 10;
- if (i < 1 || i > 10)
- {
- ErrorValN("Xn", i);
- return tcError;
- }
- gs.nAnim = i;
- break;
- #endif
-
- default:
- ErrorSwitch(argv[0]);
- return tcError;
- }
- /* 'darg' contains the value to be added to argc when we return. */
- return darg;
- }
-
-
- /* Process one command line switch passed to the program dealing with more */
- /* obscure graphics options. This is structured very much like the function */
- /* NProcessSwitchesX(), except here we know each switch begins with 'YX'. */
-
- int NProcessSwitchesRareX(argc, argv, pos)
- int argc, pos;
- char **argv;
- {
- int darg = 0, i, j;
- char ch1;
-
- ch1 = argv[0][pos+1];
- switch (argv[0][pos]) {
-
- case chNull:
- if (argc <= 2)
- {
- ErrorArgc("YX");
- return tcError;
- }
- #ifdef PCG
- i = atoi(argv[1]);
- if (!FValidResmode(i))
- {
- ErrorValN("YX", i);
- return tcError;
- }
- gs.nResHi = i;
- i = atoi(argv[2]);
-
- if (!FValidResmode(i))
- {
- ErrorValN("YX", i);
- return tcError;
- }
- gs.nResLo = i;
- gs.fBitmap = gs.fPS = gs.fMeta = fFalse;
- #endif
-
- darg += 2;
- break;
-
- case 'G':
- if (argc <= 1)
- {
- ErrorArgc("YXG");
- return tcError;
- }
- i = atoi(argv[1]);
- if (!FValidGlyphs(i))
- {
- ErrorValN("YXg", i);
- return tcError;
- }
- gs.nGlyphs = i;
- j = i/1000;
- if (FBetween(j, 1, 2))
- szDrawSign[sCap] = szDrawSign[cSign+j];
- j = (i/100)%10;
- if (FBetween(j, 1, 2))
- szDrawObject[oUra] = szDrawObject[oNorm+j];
- j = (i/10)%10;
- if (FBetween(j, 1, 2))
- szDrawObject[oPlu] = szDrawObject[oNorm+2+j];
- j = i%10;
- if (FBetween(j, 1, 3))
- szDrawObject[oLil] = szDrawObject[oNorm+4+j];
- darg++;
- break;
-
- case 'g':
- if (argc <= 1)
- {
- ErrorArgc("YXg");
- return tcError;
- }
- i = atoi(argv[1]);
- if (!FValidGrid(i))
- {
- ErrorValN("YXg", i);
- return tcError;
- }
- gs.nGridCell = i;
- darg++;
- break;
-
- case 'f':
- if (argc <= 1)
- {
- ErrorArgc("YXf");
- return tcError;
- }
- gs.fFont = atoi(argv[1]);
- darg++;
- break;
-
- #ifdef PS
- case 'p':
- if (ch1 == '0')
- {
- if (argc <= 2)
- {
- ErrorArgc("YXp0");
- return tcError;
- }
- gs.xInch = atof(argv[1]);
- gs.yInch = atof(argv[2]);
- darg += 2;
- break;
- }
- if (argc <= 1)
- {
- ErrorArgc("YXp");
- return tcError;
- }
- gs.nOrient = atoi(argv[1]);
- darg++;
- break;
- #endif
-
- default:
- ErrorSwitch(argv[0]);
- return tcError;
- }
- /* 'darg' contains the value to be added to argc when we return. */
- return darg;
- }
-
-
- /* This is the main interface to all the graphics features. This routine */
- /* is called from the main program if any of the -X switches were specified, */
- /* and it sets up for and goes and generates the appropriate graphics chart. */
- /* We return fTrue if successfull, fFalse if some non-fatal error occurred. */
-
- bool FActionX()
- {
- int i;
-
- /* Set up variables in preparation for graphics. Set the glyphs for */
- /* certain objects to point to their current setting, and if doing */
- /* constellations, give a couple stars more correct astronomical names. */
-
- #ifdef CONSTEL
- if (gs.fConstel)
- {
- szObjName[starLo-1+10] = "Alnilam"; /* Normally "Orion" */
- szObjName[starLo-1+47] = "M31"; /* Normally "Andromeda" */
- }
- #endif
-
- i = gs.nGlyphs/1000;
- szDrawSign[sCap] = szDrawSign[cSign+(i == 2 ? 2 : 1)];
-
- i = (gs.nGlyphs/100)%10;
- szDrawObject[oUra] = szDrawObject[oNorm+(i == 2 ? 2 : 1)];
-
- i = (gs.nGlyphs/10)%10;
- szDrawObject[oPlu] = szDrawObject[oNorm+2+(i == 2 ? 2 : 1)];
-
- i = gs.nGlyphs%10;
- szDrawObject[oLil] = szDrawObject[oNorm+4+(FBetween(i, 2, 3) ? i : fSouthNode ? 3 : 1)];
-
- if (fSouthNode)
- szObjectFont[oSou] = '>';
-
- /*printf("fBitmap=%d fPS=%d fMeta=%d\n", gs.fBitmap, gs.fPS, gs.fMeta);*/
- gi.fFile = (gs.fBitmap || gs.fPS || gs.fMeta) /*& 0*/;
-
- #ifdef PS
- gi.fEps = gs.fPS > fTrue;
- #endif
-
- /* First figure out what graphic mode to generate the chart in, based on */
- /* various non-X command switches, e.g. -L combined with -X, -g combined */
- /* with -X, and so on, and determine the size the window is to be, too. */
-
- if (gi.nMode == gWheel)
- {
- if (us.fWheel)
- gi.nMode = gHouse;
-
- else if (us.fGrid || us.fMidpoint)
- {
- gi.nMode = gGrid;
-
- if (us.nRel <= rcDual && us.fMidpoint && !us.fAspList)
- us.fGridConfig = fTrue;
-
- gs.xWin = gs.yWin = (gs.nGridCell + (us.nRel <= rcDual))*CELLSIZE*gi.nScale + 1;
- }
-
- else if (us.fHorizon) gi.nMode = gHorizon;
- else if (us.fOrbit) gi.nMode = gOrbit;
- else if (us.fInfluence) gi.nMode = gDisposit;
- else if (us.fAstroGraph) gi.nMode = gAstroGraph;
- else if (us.fCalendar) gi.nMode = gCalendar;
- else if (us.fEphemeris) gi.nMode = gEphemeris;
- else if (us.nRel == rcBiorhythm) gi.nMode = gBiorhythm;
- }
-
- if (fMap)
- {
- gs.xWin = nDegMax*gi.nScale;
- gs.yWin = nDegHalf*gi.nScale;
- }
-
- gi.nScaleT = gs.fPS ? PSMUL : (gs.fMeta ? METAMUL : 1);
-
- if (gi.fFile)
- {
- if (gs.xWin == 0) gs.xWin = DEFAULTX;
- if (gs.yWin == 0) gs.yWin = DEFAULTY;
- if (fSidebar) gs.xWin += SIDESIZE;
- if (gs.xWin > BITMAPX) gs.xWin = BITMAPX;
- if (gs.yWin > BITMAPY) gs.yWin = BITMAPY;
-
- BeginFileX();
-
- if (gs.fBitmap)
- {
- gi.cbBmpRow = (gs.xWin + 1) >> 1;
- gi.yBand = gs.yWin;
-
- if (!FEnsureGrid())
- return fFalse;
-
- while ((gi.bm = PAllocate((long)gi.cbBmpRow * gi.yBand, fTrue, NULL)) == NULL)
- {
- PrintWarning("The bitmap must be generated in multiple stages.");
- gi.yBand = (gi.yBand + 1) / 2;
- if (gi.yBand < 1 || gs.chBmpMode != 'B')
- return fFalse;
- }
-
- if (gi.yBand == gs.yWin)
- gi.yBand = 0;
- else
- {
- gi.yOffset = gs.yWin - gs.yWin % gi.yBand;
- if (gi.yOffset == gs.yWin)
- gi.yOffset -= gi.yBand;
- }
- }
-
- #ifdef PS
- else if (gs.fPS)
- PsBegin();
- #endif /* PS */
-
- #ifdef META
- else
- {
- if (!FEnsureGrid())
- return fFalse;
- for (gi.cbMeta = MAXMETA;
- gi.cbMeta > 0 && (gi.bm = PAllocate(gi.cbMeta, fTrue, NULL)) == NULL;
- gi.cbMeta -= MAXMETA/8)
-
- PrintWarning("Attempting to get maximum memory for metafile.");
-
- if (gi.cbMeta == 0)
- return fFalse;
-
- gs.xWin *= METAMUL; /* Increase chart sizes and scales behind the */
- gs.yWin *= METAMUL; /* scenes to make graphics look smoother. */
- gs.nScale *= METAMUL;
- }
- #endif /* META */
- InitColorsX();
- }
- #ifdef ISG
- else /* !gi.fFile */
- {
-
- #ifdef PCG
- BeginX();
- if (gs.xWin == 0 || gs.yWin == 0)
- {
- if (gs.xWin == 0) gs.xWin = xPcScreen;
- if (gs.yWin == 0) gs.yWin = yPcScreen;
- SquareX(&gs.xWin, &gs.yWin, fFalse);
- }
- else if(fSidebar)
- gs.xWin += SIDESIZE;
-
- #else /* !PCG */
- if (gs.xWin == 0 || gs.yWin == 0)
- {
- if (gs.xWin == 0) gs.xWin = DEFAULTX;
- if (gs.yWin == 0) gs.yWin = DEFAULTY;
- SquareX(&gs.xWin, &gs.yWin, fFalse);
- }
- else if (fSidebar)
- gs.xWin += SIDESIZE;
- BeginX();
- #endif /* PCG */
-
- }
- #endif /* ISG */
-
- if (gi.fFile || gs.fRoot) /* Go draw the graphic chart. */
- DrawChartX();
-
- if (gi.fFile) /* Write bitmap to file if in that mode. */
- {
- EndFileX();
-
- while (gi.yBand)
- {
- gi.yOffset -= gi.yBand;
- DrawChartX();
- EndFileX();
- }
-
- if (!gs.fPS)
- DeallocateHuge(gi.bm);
- }
- #ifdef ISG
-
- else /* !gi.fFile */
- {
-
- #ifdef X11
- if (gs.fRoot) /* Process -XB. */
- {
- XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
- XClearWindow(gi.disp, gi.root);
-
- /* If -Xn in effect with -XB, then enter infinite loop where we */
- /* calculate and animate chart, displaying on the root window. */
-
- while (gs.nAnim)
- {
- Animate(gs.nAnim, 1);
- if (!gs.fJetTrail)
- XFillRectangle(gi.disp, gi.pmap, gi.pmgc, 0, 0, gs.xWin, gs.yWin);
- DrawChartX();
- XSetWindowBackgroundPixmap(gi.disp, gi.root, gi.pmap);
- XClearWindow(gi.disp, gi.root);
- }
- }
- else
- #endif /* X11 */
-
- InteractX(); /* Window's up; process commands given to window now. */
- EndX();
- }
- #endif /* ISG */
-
- return fTrue;
- }
- #endif /* GRAPH */
-
- /* xscreen.c */
-